package com.example.test.dialogfactory;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.subjects.PublishSubject;
import java.util.concurrent.TimeUnit;

public class MainActivity82 extends AppCompatActivity {

    private static final String TAG = "MainActivity82";

    private EditText mSearch;
    private Button mConfirm;
    private TextView mText;

    public static void start( Context context ) {

        Intent starter = new Intent( context, MainActivity82.class );
        context.startActivity( starter );
    }

    @Override
    protected void onCreate( Bundle savedInstanceState ) {

        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main82 );
        initView();
        initViewAction();
    }

    private void initView() {

        mSearch = (EditText) findViewById( R.id.search );
        mConfirm = (Button) findViewById( R.id.confirm );
        mText = (TextView) findViewById( R.id.text );
    }

    private void initViewAction() {

        DebounceTextWatcher textWatcher = new DebounceTextWatcher() {
            @Override
            protected long configDebounceTime() {

                return 2000;
            }

            @Override
            public void onDebounceTextChanged( CharSequence charSequence ) {

                super.onDebounceTextChanged( charSequence );
                mText.setText( charSequence );
            }
        };
        textWatcher.attach( mSearch );

        mConfirm.setOnClickListener( new OnClickListener() {
            @Override
            public void onClick( View v ) {

                textWatcher.applyChangeImmediately();
            }
        } );
    }

    /**
     * 防抖输入,输入内容的一定时间后,使用最新的输入内容回调{@link #onDebounceTextChanged(CharSequence)}
     * 也可以调用{@link #applyChangeImmediately()},立即使用最新的输入内容回调{@link #onDebounceTextChanged(CharSequence)}
     */
    public static class DebounceTextWatcher implements TextWatcher {

        /**
         * 发射数据
         */
        private PublishSubject< CharSequence > mSubject;
        /**
         * 接受发射的数据,然后回调给用户
         */
        private final Observer< CharSequence > mObserver = new Observer< CharSequence >() {
            @Override
            public void onSubscribe( @NonNull Disposable d ) {

            }

            @Override
            public void onNext( @NonNull CharSequence charSequence ) {

                onDebounceTextChanged( charSequence );
            }

            @Override
            public void onError( @NonNull Throwable e ) {

            }

            @Override
            public void onComplete() {

                mSubject.onComplete();

                create();
            }
        };

        public DebounceTextWatcher() {

            create();
        }

        /**
         * @param editText 开始接受输入,然后按时间间隔发射数据
         */
        public void attach( EditText editText ) {

            if ( editText == null ) {
                return;
            }

            editText.removeTextChangedListener( this );
            editText.addTextChangedListener( this );
        }

        /**
         * 创建变量
         */
        private void create() {

            mSubject = PublishSubject.create();
            mSubject.debounce( configDebounceTime(), TimeUnit.MILLISECONDS )
                .observeOn( AndroidSchedulers.mainThread() )
                .subscribe( mObserver );
        }

        /**
         * 配置{@link #create()}中最少需要多少时间才发射数据
         *
         * @return 时间:最少需要多少才发射数据
         */
        protected long configDebounceTime() {

            return 1500;
        }

        @Override
        public void beforeTextChanged( CharSequence s, int start, int count, int after ) {

        }

        @Override
        public void onTextChanged( CharSequence s, int start, int before, int count ) {

        }

        @Override
        public final void afterTextChanged( Editable s ) {

            mSubject.onNext( s );
        }

        /**
         * 立即回调
         */
        public void applyChangeImmediately() {

            mSubject.onComplete();
        }

        /**
         * @param charSequence 回调,一段时间内最新的输入
         */
        public void onDebounceTextChanged( @NonNull CharSequence charSequence ) {

        }
    }
}